package com.example.service;

import cn.hutool.core.date.DateField;
import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.lang.Dict;
import cn.hutool.core.util.RandomUtil;
import com.example.common.enums.OrdersEnum;
import com.example.common.enums.RoleEnum;
import com.example.entity.Account;
import com.example.entity.Address;
import com.example.entity.Goods;
import com.example.entity.Orders;
import com.example.mapper.OrdersMapper;
import com.example.utils.TokenUtils;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import javax.annotation.Resource;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 订单信息业务处理
 **/
@Service
public class OrdersService {

    @Resource
    private OrdersMapper ordersMapper;

    @Resource
    private GoodsService goodsService;

    @Resource
    private AddressService addressService;

    /**
     * 新增订单
     *
     * @param orders 订单对象，包含订单的相关信息
     */
    public void add(Orders orders) {
        // 获取订单中的商品ID
        Integer goodsId = orders.getGoodsId();
        // 根据商品ID查询商品信息
        Goods goods = goodsService.selectById(goodsId);
        // 设置订单中的商品名称
        orders.setGoodsName(goods.getName());
        // 设置订单中的商品图片
        orders.setGoodsImg(goods.getImg());
        // 设置订单中的销售者ID
        orders.setSaleId(goods.getUserId());
        // 获取订单中的地址ID
        Integer addressId = orders.getAddressId();
        // 根据地址ID查询地址信息
        Address address = addressService.selectById(addressId);
        // 设置订单中的收货人姓名
        orders.setUserName(address.getName());
        // 设置订单中的收货人电话
        orders.setPhone(address.getPhone());
        orders.setAddress(address.getAddress());
        // 获取当前登录用户信息
        Account currentUser = TokenUtils.getCurrentUser();
        // 设置订单中的购买者ID
        orders.setUserId(currentUser.getId());
        // 设置订单状态为“待支付”
        orders.setStatus(OrdersEnum.PENDING_PAYMENT.value);
        // 生成订单号，包含当前时间戳和随机字符串
        orders.setOrderNo(System.currentTimeMillis() + RandomUtil.randomNumbers(7));//20位订单号
        // 设置订单创建时间
        orders.setTime(DateUtil.now());
        // 设置订单总金额
        orders.setTotal(goods.getPrice());
        // 插入订单信息到数据库
        ordersMapper.insert(orders);
    }

    /**
     * 删除
     */
    public void deleteById(Integer id) {
        ordersMapper.deleteById(id);
    }

    /**
     * 批量删除
     */
    public void deleteBatch(List<Integer> ids) {
        for (Integer id : ids) {
            ordersMapper.deleteById(id);
        }
    }

    /**
     * 修改
     */
    public void updateById(Orders orders) {
        ordersMapper.updateById(orders);
    }

    /**
     * 根据ID查询
     */
    public Orders selectById(Integer id) {
        return ordersMapper.selectById(id);
    }

    /**
     * 查询所有
     */
    public List<Orders> selectAll(Orders orders) {
        return ordersMapper.selectAll(orders);
    }

    /**
     * 买家分页查询
     */
    public PageInfo<Orders> selectPage(Orders orders, Integer pageNum, Integer pageSize) {
        // 获取当前登录用户信息
        Account currentUser = TokenUtils.getCurrentUser();
        if(RoleEnum.USER.name().equals(currentUser.getRole())){
            // 设置订单中的购买者ID
            orders.setUserId(currentUser.getId());
        }
        PageHelper.startPage(pageNum, pageSize);
        List<Orders> list = ordersMapper.selectAll(orders);
        return PageInfo.of(list);
    }
    /**
     * 卖家分页查询
     */
    public PageInfo<Orders> selectSalePage(Orders orders, Integer pageNum, Integer pageSize) {
        // 获取当前登录用户信息
        Account currentUser = TokenUtils.getCurrentUser();
        if(RoleEnum.USER.name().equals(currentUser.getRole())){
            // 设置订单中的购买者ID
            orders.setSaleId(currentUser.getId());
        }
        PageHelper.startPage(pageNum, pageSize);
        List<Orders> list = ordersMapper.selectAll(orders);
        return PageInfo.of(list);
    }
    public Orders selectByOrderNo(String orderNo) {
        return ordersMapper.selectByOrderNo(orderNo);
    }

    /**
     * 查询并整理订单数据
     * 本方法主要目的是从所有订单中筛选出已完成的订单，并在指定的时间范围内汇总这些订单的总金额
     * 汇总是按天进行的，即方法返回的数据列表是每天的订单总金额
     *
     * @return 返回一个Dict类型的列表，列表中的每个Dict对象包含两天信息：一天的日期和该日期的订单总金额
     */
    public List<Dict> selectLine() {
        // 初始化字典列表，用于存储最终的汇总数据
        List<Dict> dictList = new ArrayList<>();
        // 获取所有已完成的订单列表
        List<Orders> ordersList = ordersMapper.selectAll(null).stream()
                .filter(orders -> OrdersEnum.COMPLETED.value.equals(orders.getStatus()))
                .collect(Collectors.toList());
        // 获取当前日期
        Date now = new Date();
        // 计算一周前的日期，用于确定汇总数据的时间范围
        DateTime start = DateUtil.offsetDay(now, -8);
        DateTime end = DateUtil.offsetDay(now, -1);
        // 生成一周内的日期列表，用于后续的数据汇总
        List<DateTime> dateTimes = DateUtil.rangeToList(start, end, DateField.DAY_OF_WEEK);
        // 格式化日期列表，并按顺序排列
        List<String> dateList = dateTimes.stream()
                //将DateTime流转换为字符串流
                .map(DateUtil::formatDate)
                // 按自然顺序排序
                .sorted(Comparator.naturalOrder())
                .collect(Collectors.toList());
        // 遍历日期列表，对每天的订单总金额进行汇总
        for(String date : dateList){
            // 过滤出指定日期的订单，并计算这些订单的总金额
            BigDecimal total = ordersList.stream()
                    //过滤对应天数的订单
                    .filter(orders -> orders.getTime().contains(date))
                    .map(Orders::getTotal)
                    .reduce(BigDecimal::add)
                    .orElse(BigDecimal.ZERO);
            // 创建字典对象，存储日期和对应的订单总金额
            Dict dict = Dict.create().set("name", date).set("value", total);
            // 将字典对象添加到列表中
            dictList.add(dict);
        }
        // 返回汇总数据列表
        return dictList;
    }

    /**
     * 查询并汇总已完成订单的销售数据
     *
     * 本方法首先获取所有已完成的订单，然后汇总每个销售员的总销售额，
     * 最后以字典列表的形式返回这些汇总数据
     *
     * @return 返回一个字典列表，列表中每个字典对象包含销售员名称和对应的总销售额
     */
    public List<Dict> selectBar() {
    // 初始化字典列表，用于存储最终的汇总数据
    List<Dict> dictList = new ArrayList<>();

    // 获取所有已完成的订单列表
    List<Orders> ordersList = ordersMapper.selectAll(null).stream()
            .filter(orders -> OrdersEnum.COMPLETED.value.equals(orders.getStatus()))
            .collect(Collectors.toList());

    // 去重销售员 ID
    Set<Integer> saleIdList = ordersList.stream()
            .map(Orders::getSaleId) // 使用 getSaleId 方法
            .filter(Objects::nonNull) // 过滤掉 null 值
            .collect(Collectors.toSet());

    // 遍历销售员 ID 列表，对每个销售员的订单总金额进行汇总
    for (Integer saleId : saleIdList) {
        // 过滤出指定销售员 ID 的订单，并计算这些订单的总金额
        BigDecimal total = ordersList.stream()
                .filter(orders -> Objects.nonNull(orders.getSaleId()) && orders.getSaleId().equals(saleId)) // 使用 getSaleId 方法
                .map(Orders::getTotal)
                .reduce(BigDecimal::add)
                .orElse(BigDecimal.ZERO);

        // 获取销售员名称
        String saleName = ordersList.stream()
                .filter(orders -> Objects.nonNull(orders.getSaleId()) && orders.getSaleId().equals(saleId))
                .findFirst()
                .map(Orders::getSaleName)
                .orElse("未知卖家"+saleId);

        Dict dict = Dict.create().set("name", saleName).set("value", total);
        // 将字典对象添加到列表中
        dictList.add(dict);
    }

    // 返回汇总数据列表
    return dictList;
}

}